/*
If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.

Anser:
Time:
*/
package main

import (
	"fmt"
	"strings"
	"time"
)

var mnum = map[int]string{
	1:   "one",
	2:   "two",
	3:   "three",
	4:   "four",
	5:   "five",
	6:   "six",
	7:   "seven",
	8:   "eight",
	9:   "nine",
	10:  "ten",
	11:  "eleven",
	12:  "twelve",
	13:  "thirteen",
	14:  "fourteen",
	15:  "fifteen",
	16:  "sixteen",
	17:  "seventeen",
	18:  "eighteen",
	19:  "nineteen",
	20:  "twenty",
	30:  "thirty",
	40:  "forty",
	50:  "fifty",
	60:  "sixty",
	70:  "seventy",
	80:  "eighty",
	90:  "ninety",
	100: "hundred",
}

func main() {
	tstart := time.Now()
	sum := len("one thousand") - 1
	for i := 1; i < 1000; i++ {
		sum += numEnLen(i)
	}
	fmt.Println(sum)
	tend := time.Now()
	fmt.Println(tend.Sub(tstart))
}

// numEnLen 返回英文长度
func numEnLen(n int) int {
	s := strings.Replace(numToEn("", n), " ", "", -1)
	return len(s)
}

// numToEn 返回英文
func numToEn(s string, n int) string {
	if n < 20 {
		return fmt.Sprintf("%s%s", s, mnum[n])
	} else if n < 100 {
		if n%10 == 0 {
			return fmt.Sprintf("%s%s", s, mnum[n])
		}
		return numToEn(fmt.Sprintf("%s%s ", s, mnum[n-n%10]), n%10)
	}
	if n%100 == 0 {
		return fmt.Sprintf("%s %s", mnum[n/100], mnum[100])
	}
	return numToEn(fmt.Sprintf("%s %s and ", mnum[n/100], mnum[100]), n%100)
}
